{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 课程1.2---Numpy通用函数\n",
    "## 基本操作"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0 1 2 3 4 5 6 7 8 9] \n",
      " [0 1 2 3 4 5 6 7 8 9]\n",
      "[[1. 1.]\n",
      " [1. 1.]\n",
      " [1. 1.]\n",
      " [1. 1.]\n",
      " [1. 1.]] \n",
      " [[1. 1. 1. 1. 1.]\n",
      " [1. 1. 1. 1. 1.]]\n",
      "--------------------------------\n",
      "[0 1 2 3 4 5 6 7 8 9] \n",
      " [[0 1 2 3 4]\n",
      " [5 6 7 8 9]]\n",
      "[[0. 0. 0. 0. 0. 0. 0. 0.]\n",
      " [0. 0. 0. 0. 0. 0. 0. 0.]\n",
      " [0. 0. 0. 0. 0. 0. 0. 0.]]\n",
      "[[ 0  1  2  3]\n",
      " [ 4  5  6  7]\n",
      " [ 8  9 10 11]]\n",
      "--------------------------------\n",
      "[[0 1 2 3]\n",
      " [4 0 1 2]\n",
      " [3 4 0 1]]\n"
     ]
    }
   ],
   "source": [
    "# 数组形状：.T / .reshape() / .resize()\n",
    "\n",
    "import numpy as np\n",
    "ar1 = np.arange(10)\n",
    "ar2 = np.ones((5,2))\n",
    "print(ar1, '\\n', ar1.T)\n",
    "print(ar2, '\\n', ar2.T)\n",
    "print(\"--------------------------------\") \n",
    "# .T方法：转置，例如：原shape为(3,4) / (2,3,4),则转置结果为(4,3) / (4,3,2)--->所以一维数组转置之后结果不变\n",
    "\n",
    "ar3 = ar1.reshape(2,5)       # 用途1：直接将已有数组改变形状\n",
    "ar4 = np.zeros((4,6)).reshape(3,8)     # 用途2：生成数组后直接改变形状\n",
    "ar5 = np.reshape(np.arange(12),(3,4))  # 用途3：参数内部添加数组，目标形状。\n",
    "print(ar1, '\\n', ar3)\n",
    "print(ar4)\n",
    "print(ar5)\n",
    "print(\"--------------------------------\")\n",
    "# numpy.reshape(a, newshape, order = 'C'): 为数组提供新形状，而不更改数据，所以元素数量需要一致！\n",
    "\n",
    "ar6 = np.resize(np.arange(5),(3,4))\n",
    "print(ar6)\n",
    "# numpy.reshape(a, new_shape): 返回具有指定形状的新数组，如果必要可以重复填充所需数量的元素(多减少加)\n",
    "# 注意了：.T / .reshape() / .resize()都是生成新的数组！！！"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "[0 1 9 3 4 5 6 7 8 9] [0 1 9 3 4 5 6 7 8 9]\n",
      "False\n",
      "[9 1 9 3 4 5 6 7 8 9] [0 1 9 3 4 5 6 7 8 9]\n"
     ]
    }
   ],
   "source": [
    "# 数组复制\n",
    "\n",
    "ar1 = np.arange(10)\n",
    "ar2 = ar1\n",
    "print(ar2 is ar1)\n",
    "ar1[2] = 9\n",
    "print(ar1, ar2)\n",
    "# 回忆Python的赋值逻辑：指向内存中生成的一个值--->这里ar1和ar2指向同一个值，所以ar1改变，ar2也一起改变\n",
    "\n",
    "ar3 = ar1.copy()\n",
    "print(ar3 is ar1)\n",
    "ar1[0] = 9\n",
    "print(ar1, ar3)\n",
    "# copy方法生成数组及其数据的完整拷贝\n",
    "# 再次提醒：.T / .reshape() / .resize()都是生成新的数组！！！"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0. 1. 2. 3. 4. 5. 6. 7. 8. 9.] float64\n",
      "---------------------------------\n",
      "[0 1 2 3 4 5 6 7 8 9] int32\n",
      "[0. 1. 2. 3. 4. 5. 6. 7. 8. 9.] float64\n"
     ]
    }
   ],
   "source": [
    "# 数组类型转换：.astype()\n",
    "\n",
    "ar1 = np.arange(10,dtype = float)\n",
    "print(ar1, ar1.dtype)\n",
    "print(\"---------------------------------\")\n",
    "# 可以在参数位置设置数据类型\n",
    "\n",
    "ar2 = ar1.astype(np.int32)\n",
    "print(ar2, ar2.dtype)\n",
    "print(ar1, ar1.dtype)\n",
    "# a.astype()  转换数据类型\n",
    "# 注意：养成好习惯，数据类型用np.int32，而不是直接int32"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0 1 2 3 4] (5,)\n",
      "[5 6 7 8] (4,)\n",
      "[0 1 2 3 4 5 6 7 8] (9,)\n",
      "[[1]\n",
      " [2]\n",
      " [3]] (3, 1)\n",
      "[['a']\n",
      " ['b']\n",
      " ['c']] (3, 1)\n",
      "[['1' 'a']\n",
      " ['2' 'b']\n",
      " ['3' 'c']] (3, 2)\n",
      "---------------------------------\n",
      "[0 1 2 3 4] (5,)\n",
      "[5 6 7 8 9] (5,)\n",
      "[[0 1 2 3 4]\n",
      " [5 6 7 8 9]] (2, 5)\n",
      "[[1]\n",
      " [2]\n",
      " [3]] (3, 1)\n",
      "[['a']\n",
      " ['b']\n",
      " ['c']\n",
      " ['d']] (4, 1)\n",
      "[['1']\n",
      " ['2']\n",
      " ['3']\n",
      " ['a']\n",
      " ['b']\n",
      " ['c']\n",
      " ['d']] (7, 1)\n",
      "---------------------------------\n",
      "[0 1 2 3 4] (5,)\n",
      "[5 6 7 8 9] (5,)\n",
      "[[0 1 2 3 4]\n",
      " [5 6 7 8 9]] (2, 5)\n",
      "[[0 5]\n",
      " [1 6]\n",
      " [2 7]\n",
      " [3 8]\n",
      " [4 9]] (5, 2)\n"
     ]
    }
   ],
   "source": [
    "# 数组堆叠\n",
    "\n",
    "a = np.arange(5)         # a为一维数组，5个元素\n",
    "b = np.arange(5,9)       # b为一维数组，4个元素\n",
    "ar1 = np.hstack((a,b))   # 注意：((a,b))---这里形状可以不一样，横向连接\n",
    "print(a, a.shape)\n",
    "print(b, b.shape)\n",
    "print(ar1, ar1.shape)\n",
    "a = np.array([[1],[2],[3]])         # a为二维数组，3行1列\n",
    "b = np.array([['a'],['b'],['c']])   # b为二维数组，3行1列\n",
    "ar2 = np.hstack((a,b))              # 注意：((a,b))---这里形状必须一样，横向连接\n",
    "print(a, a.shape)\n",
    "print(b, b.shape)\n",
    "print(ar2, ar2.shape)\n",
    "print(\"---------------------------------\")\n",
    "# numpy.hstack(tup): 水平(按列顺序)堆叠数组\n",
    "\n",
    "a = np.arange(5)         \n",
    "b = np.arange(5,10)       \n",
    "ar1 = np.vstack((a,b))   # 注意：((a,b))---这里形状必须一样，竖向连接\n",
    "print(a, a.shape)\n",
    "print(b, b.shape)\n",
    "print(ar1, ar1.shape)\n",
    "a = np.array([[1],[2],[3]])         \n",
    "b = np.array([['a'],['b'],['c'],['d']]) \n",
    "ar2 = np.vstack((a,b))  # 注意：((a,b))---这里形状可以不一样，竖向连接\n",
    "print(a, a.shape)\n",
    "print(b, b.shape)\n",
    "print(ar2, ar2.shape)\n",
    "print(\"---------------------------------\")\n",
    "# numpy.vstack(tup): 垂直(按行顺序)堆叠数组\n",
    "\n",
    "a = np.arange(5)         \n",
    "b = np.arange(5,10)       \n",
    "ar1 = np.stack((a,b))          # 默认为垂直堆叠\n",
    "ar2 = np.stack((a,b),axis = 1) # axis = 0 竖向 ， axis = 1 横向。\n",
    "print(a, a.shape)\n",
    "print(b, b.shape)\n",
    "print(ar1, ar1.shape)\n",
    "print(ar2, ar2.shape)\n",
    "# numpy.stack(arrays, axis = 0): 沿着新轴连接的序列，形状必须一样\n",
    "# 重点解释axis参数的意思：假设两个数组[1 2 3]和[4 5 6]，shape均为(3,0)\n",
    "# axis = 0：[[1 2 3] [4 5 6]],shape为（2,3）\n",
    "# axis = 1： [[1 4] [2 5] [3 6]],shape为（3,2）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 0  1  2  3]\n",
      " [ 4  5  6  7]\n",
      " [ 8  9 10 11]\n",
      " [12 13 14 15]]\n",
      "[array([[ 0,  1],\n",
      "       [ 4,  5],\n",
      "       [ 8,  9],\n",
      "       [12, 13]]), array([[ 2,  3],\n",
      "       [ 6,  7],\n",
      "       [10, 11],\n",
      "       [14, 15]])] <class 'list'>\n",
      "[array([[0, 1, 2, 3]]), array([[4, 5, 6, 7]]), array([[ 8,  9, 10, 11]]), array([[12, 13, 14, 15]])] <class 'list'>\n"
     ]
    }
   ],
   "source": [
    "# 数组拆分\n",
    "\n",
    "ar = np.arange(16).reshape(4,4)\n",
    "ar1 = np.hsplit(ar, 2)\n",
    "print(ar)\n",
    "print(ar1, type(ar1))\n",
    "# numpy.hsplit(ary, indices_or_sections)：将数组水平(逐列)拆分为多个子数组--->按列拆分\n",
    "# 输出结果为列表，列表中元素为数组\n",
    "\n",
    "ar2 = np.vsplit(ar, 4)\n",
    "print(ar2, type(ar2))\n",
    "# numpy.vsplit(ary, indices_or_sections)：将数组垂直(行方向)拆分为多个子数组--->按行拆分"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[10 11 12]\n",
      " [13 14 15]]\n",
      "[[ 0  2  4]\n",
      " [ 6  8 10]]\n",
      "[[1.         0.5        0.33333333]\n",
      " [0.25       0.2        0.16666667]]\n",
      "[[0.         1.         1.41421356]\n",
      " [1.73205081 2.         2.23606798]]\n",
      "2.5\n",
      "5\n",
      "0\n",
      "1.707825127659933\n",
      "2.9166666666666665\n",
      "15 [3 5 7]\n",
      "[1 2 3 4 5 6]\n"
     ]
    }
   ],
   "source": [
    "# 数组的简单运算\n",
    "\n",
    "ar = np.arange(6).reshape(2,3)\n",
    "print(ar + 10)    # 加法\n",
    "print(ar * 2)    # 乘法\n",
    "print(1 / (ar + 1))  # 除法\n",
    "print(ar ** 0.5)     # 幂\n",
    "# 与标量的运算\n",
    "\n",
    "print(ar.mean())     # 求平均值\n",
    "print(ar.max())     # 求最大值\n",
    "print(ar.min())     # 求最小值\n",
    "print(ar.std())     # 求标准差\n",
    "print(ar.var())     # 求方差\n",
    "print(ar.sum(),np.sum(ar,axis = 0))          # 求和：np.sum()--->axis = 0，按列求和；axis = 1，按行求和\n",
    "print(np.sort(np.array([1,4,3,2,5,6])))     # 排序\n",
    "# 常用函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
